###################################
#K最近邻(k-NearestNeighbor，KNN)分类算法。
#该方法的思路是：
#  如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别，则该样本也属于这个类别。
###################################

library(ggvis)

head(iris)
##利用ggvis包，绘制散点图
iris %>%ggvis(~Sepal.Length, ~Sepal.Width, fill=~Species) %>% layer_points()
iris %>%ggvis(~Petal.Length, ~Petal.Width, fill=~Species) %>% layer_points()

##数据结构分析法
str(iris)
table(iris$Species)
round(prop.table(table(iris$Species))*100,digits=1 )

summary(iris)
summary(iris[c("Petal.Width","Sepal.Width")])

##使用机器学习算法KNN
library(class)
##归一化函数，最大-最小化归一化
normalize <- function(x){
  num <- x - min(x)
  denom <- max(x) - min(x)
  return(num/denom)
}

iris_norm <-as.data.frame(lapply(iris[,1:4], normalize))
summary(iris_norm)

##训练数据集和测试数据集
set.seed(1234)
ind <- sample(2,nrow(iris), replace=TRUE, prob=c(0.67, 0.33))

iris_train <-iris[ind==1, 1:4]
iris_test <-iris[ind==2, 1:4]

train_label <-iris[ind==1, 5]
test_label <-iris[ind==2, 5]

##构建KNN模型
iris_pred <-knn(train=iris_train, test=iris_test, cl=train_label, k=3)

##模型评价
table(test_label,iris_pred)

library(gmodels)
CrossTable(x=test_label,y=iris_pred, prop.chisq=FALSE)

################################################
##数据集分为训练集和测试集
index <-sample(1:nrow(iris), 100)
iris.train <-iris[index, ]
iris.test <-iris[-index, ]

##利用kNN算法对测试集进行分类
library(class)
result.KNN <-knn(train=subset(iris.train,select=-Species), test=subset(iris.test,select=-Species), cl=iris.train$Species)

##生成结果集的混淆矩阵
table(result.KNN, iris.test$Species)


